<?php
namespace api\modules\v1\models;

use Yii;
use api\components\ApiModel;
use common\models\ARAddressout;
use common\models\ARAddressin;
use common\models\ARCoinType;
use yii\helpers\ArrayHelper;
use common\models\Message;
use common\models\CoinWallet;

/**
 * 币地址模型
 * @author WJ
 */
class Address extends ApiModel
{
    const SCENARIO_OUT_LIST = 'out_list';
    const SCENARIO_OUT_BIND = 'out_bind';
    const SCENARIO_OUT_UPDATE = 'out_update';
    const SCENARIO_OUT_DELETE = 'out_delete';
    const SCENARIO_OUT_DEFAULT = 'out_default';
    const SCENARIO_RECHARGEADDRESS = 'recharge_address';

    public $address_id;
    public $address;
    public $coin;
    public $name;
    public $code;
    public $mode;
    public $size;
    public $page;

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        $attributes = [
            'address_id' => '地址编号',
            'coin'       => '币种',
            'name'       => '地址标签',
            'code'       => '校验码',
            'mode'       => '消息方式',
            'size'       => '分页大小',
            'page'       => '当前页',
        ];
        if ($this->scenario == self::SCENARIO_OUT_BIND) {
            $attributes['address'] = '提币地址';
        } else {
            $attributes['address'] = '入币地址';
        }
        return $attributes;
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        return [
            self::SCENARIO_OUT_LIST        => ['coin'],
            self::SCENARIO_OUT_BIND        => ['address', 'coin', 'name', 'code', 'mode'],
            self::SCENARIO_OUT_UPDATE      => ['address_id', 'name'],
            self::SCENARIO_OUT_DELETE      => ['address_id'],
            self::SCENARIO_OUT_DEFAULT     => ['address_id'],
            self::SCENARIO_RECHARGEADDRESS => ['coin'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['address_id', 'address', 'coin', 'code', 'mode', 'name', 'is_default'], 'trim'],
            [['address_id', 'address', 'coin', 'code'], 'required'],
            ['address', 'string', 'length' => 64],
            ['code', 'string', 'length' => 6],
            ['coin', 'in', 'range' => ARCoinType::find()->where(['status' => ARCoinType::STATUS_ACTIVE])->select('id')->asArray()->column()],
            ['mode', 'default', 'value' => Message::MODE_EMAIL],
            ['mode', 'in', 'range' => [Message::MODE_SMS, Message::MODE_EMAIL]],
            ['size', 'default', 'value' => 10],
            ['page', 'default', 'value' => 1],
        ];
    }
    /**
     * 获取资产安全码
     * @param Object $row 数据记录
     */
    public static function getAddressSecufity($row)
    {
        $salt = Yii::$app->params['salt']['address'];
        $param = [
            'uid'     => $row->uid,
            'address' => $row->address,
            'coin'    => $row->coin,
        ];
        $addtime = $row->security_at;
        $code = self::getSecurity($param, $addtime, $salt);
        return $code;
    }

    /**
     * 校验资产安全码
     * @param Object $row 数据记录
     */
    public static function verifyAddressSecufity($row)
    {
        $code = self::getAddressSecufity($row);
        if ($code === $row->security_code) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 提币地址列表
     */
    public function listOutAddr()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $sql = ARAddressout::find()->where(['uid' => Yii::$app->user->id, 'coin' => $this->coin]);
        $count = $sql->count();
        $data = $sql
        // ->limit($this->size)->offset($this->size * ($this->page - 1))
        ->all();
        $row = ArrayHelper::toArray($data, [
            ARAddressout::className() => [
                'id',
                'address',
                'name',
                'is_default',
                'security'     => function ($row) {
                    $flag = self::verifyAddressSecufity($row);
                    return ($flag) ? ARAddressout::SECURITY_SAFE : ARAddressout::SECURITY_UNSAFE;
                },
                'created_time' => function ($row) {
                    return Yii::$app->formatter->asDatetime($row->created_at);
                },
                'updated_time' => function ($row) {
                    return Yii::$app->formatter->asDatetime($row->updated_at);
                },
            ],
        ]);
        return ['count' => $count, 'row' => $row];
    }

    /**
     * 绑定提币地址
     */
    public function bindOutAddr()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $user = self::getUser();
        //验证验证码
        if ($this->mode == Message::MODE_EMAIL) {
            if (!$user->email) {
                self::throwError('100013');
            }
            list($flag, $data) = Message::validateEmailCode('binding', $this->code, $user->email);
            if (!$flag) {
                self::throwError('100011');
            }
        } else {
            if (!$user->mobile) {
                self::throwError('100014');
            }
            list($flag, $data) = Message::validateMobileCode('binding', $this->code, $user->mobile);
            if (!$flag) {
                self::throwError('100012');
            }
        }
        $uid = Yii::$app->user->id;
        $is_default = ARAddressout::DEFAULT_NOT;
        $count = ARAddressout::find()->where(['uid' => $uid])->count();
        if ($count == 0) {
            //第一条提币地址直接设为默认
            $is_default = ARAddressout::DEFAULT_IS;
        } else {
            $result = ARAddressout::find()->where(['uid' => $uid, 'address' => $this->address])->one();
            if ($result) {
                self::throwError('100041');
            }
        }
        $address = new ARAddressout();
        $address->attributes = $this->attributes;
        $address->uid = $uid;
        $address->is_default = $is_default;
        $address->security_at = Yii::$app->formatter->asTimeStamp('now');

        $security_code = self::getAddressSecufity($address);
        $address->security_code = $security_code;
        if (!$address->save()) {
            self::getErrorMessge($address);
        }
        return ['address_id' => $address->id];
    }

    /**
     * 修改提币地址
     */
    public function updateOutAddr()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $uid = Yii::$app->user->id;
        $address = ARAddressout::find()->where(['id' => $this->address_id, 'uid' => $uid])->one();
        if (!$address) {
            self::throwError('100042');
        }
        //验证原安全码
        $flag = self::verifyAddressSecufity($address);
        if (!$flag) {
            self::throwError('100045');
        }
        $address->attributes = array_filter($this->attributes);
        if (!empty($address->dirtyAttributes)) {
            $address->security_at = Yii::$app->formatter->asTimeStamp('now');

            $security_code = self::getAddressSecufity($address);
            $address->security_code = $security_code;
            if(!$address->update()){
                self::getErrorMessge($address);
            }
        }
        return ['address_id' => $address->id];
    }

    /**
     * 删除提币地址
     */
    public function deleteOutAddr()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $address = ARAddressout::findOne(['id' => $this->address_id, 'uid' => Yii::$app->user->id]);
        if (!$address) {
            self::throwError('100042');
        }
        $tran = Yii::$app->db->beginTransaction();
        try {
            $address->delete();

            $new_default = ARAddressout::findOne(['uid' => Yii::$app->user->id]);
            if ($new_default) {
                $new_default->is_default = ARAddressout::DEFAULT_IS;
                $new_default->update();
            }
            $tran->commit();
        } catch (\Exception $e) {
            $tran->rollBack();
            throw $e;
        }
        return ['address_id' => $address->id];
    }

    /**
     * 设置默认提币地址
     */
    public function setDefault()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $address = ARAddressout::findOne(['id' => $this->address_id, 'uid' => Yii::$app->user->id]);
        if (!$address) {
            self::throwError('100042');
        }

        $default = ARAddressout::findOne(['uid' => Yii::$app->user->id, 'is_default' => ARAddressout::DEFAULT_IS]);
        if ($default && $default->id != $address->id) {
            $tran = Yii::$app->db->beginTransaction();
            try {
                $default->is_default = ARAddressout::DEFAULT_NOT;
                $default->security_at = Yii::$app->formatter->asTimeStamp('now');
                $security_code = self::getAddressSecufity($default);
                $default->security_code = $security_code;
                $default->update();

                $address->is_default = ARAddressout::DEFAULT_IS;
                $address->security_at = Yii::$app->formatter->asTimeStamp('now');
                $security_code = self::getAddressSecufity($address);
                $address->security_code = $security_code;
                $address->update();
                $tran->commit();
            } catch (\Exception $e) {
                $tran->rollBack();
                throw $e;
            }
        } elseif (!$default) {
            $address->is_default = ARAddressout::DEFAULT_IS;
            $address->security_at = Yii::$app->formatter->asTimeStamp('now');
            $security_code = self::getAddressSecufity($address);
            $address->security_code = $security_code;
            $address->update();
        }
        return ['address_id' => $address->id];
    }

    /**
     * 获取入币地址
     * @author CGA
     */
    public function getRechargeAddress()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $uid = Yii::$app->user->id;
        $row = ARAddressin::find()->where(['uid' => $uid, 'coin' => $this->coin])->one();
        if ($row) {
            $verify = self::verifyAddressSecufity($row);
            if (!$verify) {
                self::throwError('100001');
            } else {
                return [
                    'id'      => $row->id,
                    'coin'    => $row->coin,
                    'address' => $row->address,
                ];
            }
        } else {
            $address = CoinWallet::getNewAddress($this->coin);
            $row = ARAddressin::findOne(['coin' => $this->coin, 'address' => $address]);
            if ($row) {
                self::throwError('100046');
            }
            $row = new ARAddressin();
            $row->uid = $uid;
            $row->coin = $this->coin;
            $row->address = $address;
            $row->security_at = Yii::$app->formatter->asTimeStamp('now');
            $security_code = self::getAddressSecufity($row);
            $row->security_code = $security_code;
            if (!$row->save()) {
                self::throwError('100045');
            } else {
                return [
                    'id'      => $row->id,
                    'coin'    => $row->coin,
                    'address' => $row->address,
                ];
            }
        }
    }
}
